﻿using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WebApi.Models.Common;

namespace WebApi.Commons.Helpers
{
    public class JWTHelper
    {
        /// <summary>
        /// 创建JWT
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static string CreateJWTToken(UserInfoModel user)
        {
            var jwtConfig = ConfigHelper.GetJwtConfig();
            var JWToken = new JwtSecurityToken(
                    issuer: jwtConfig.Issuer,
                    audience: jwtConfig.Audience,
                    claims: GetUserClaims(user),
                    notBefore: new DateTimeOffset(DateTime.Now).DateTime,
                    expires: new DateTimeOffset(DateTime.Now.AddSeconds(jwtConfig.Expires)).DateTime,
                    signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.Secret)), SecurityAlgorithms.HmacSha256Signature)
                );
            var token = new JwtSecurityTokenHandler().WriteToken(JWToken);
            return token;
        }

        /// <summary>
        /// 构建claim
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private static IEnumerable<Claim> GetUserClaims(UserInfoModel user)
        {
            IEnumerable<Claim> claims = new Claim[]
            {
                new Claim("ID", user.Id.ToString()),
                new Claim("NAME", user.Name ?? string.Empty),
                new Claim("ACCOUNT", user.Account.ToString())
            };
            return claims;
        }

        /// <summary>
        /// 解析JWT
        /// </summary>
        /// <param name="token"></param>
        public static UserInfoModel? JWTDecode(string token)
        {
            try
            {
                if (string.IsNullOrEmpty(token))
                {
                    return null;
                }
                var auth = token.Split(" ")[1].Split('.');
                var user = JsonConvert.DeserializeObject<UserInfoModel>(Base64UrlEncoder.Decode(auth[1]));
                return user;
            }
            catch (Exception ex)
            {
                LoggerHelper.Error(LogEnum.System, "解析JWT异常", ex);
                return null;
            }
        }

        /// <summary>
        /// 是否过期
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool IsExpired(string token)
        {
            try
            {
                var handler = new JwtSecurityTokenHandler();
                var jwt = handler.ReadJwtToken(token);

                if (jwt == null)
                {
                    return true;
                }

                if (jwt.ValidTo < DateTime.Now)
                {
                    return true;
                }
                return false;
            }
            catch
            {
                return true;
            }
        }
    }
}
